
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "hal.h"   

typedef uint8_t (*SPI_Nor_Read_Status_Func)(void);  

typedef uint8_t (*SPI_Nor_Write_Status_Func)(uint8_t status1, uint8_t status2);  

uint16_t SPI_Read_Status_Register(void)
{
    SPI_Flash_Parameter para; 
    uint8_t status_1, status_2;  
    uint8_t result; 
    
    para.Delay = NORFLASH_OPRA_DELAY;    
    result = ((SPI_Nor_Func)(0x00001df9))(&para);  
    
    status_1 = ((SPI_Nor_Read_Status_Func)(0x00001cf1))();                 
    status_2 = ((SPI_Nor_Read_Status_Func)(0x00001d3d))();   
 
    ((SPI_Nor_Func)(0x00001e51))(&para);     
    
    return (status_1 | ((uint16_t)status_2 << 8) );       
}

void SPI_Read_Write_Register(uint8_t status1, uint8_t status2)  
{
    SPI_Flash_Parameter para; 
    uint8_t status_1, status_2;  
    
    para.Delay = NORFLASH_OPRA_DELAY;    
    ((SPI_Nor_Func)(0x00001df9))(&para); 
    
    ((SPI_Nor_Write_Status_Func)0x00001ee1)(status1, status2);      
    
    ((SPI_Nor_Func)(0x00001e51))(&para);        
}



// out_data: return 16bit status register 
// return value: 0,PASS; 1,FAIL  

uint8_t SPI_Protect_4KB(uint16_t *out_data)  
{
    uint32_t sr; 
    uint16_t status_read_first_time, status_read_second_time;  
    uint8_t status1, status2, result;  
     
    result = 0;
    status_read_first_time = 0; 
    status_read_second_time = 0; 
    
    sr = HAL_NORFLASH_EnterCritical(); 
    status_read_first_time = SPI_Read_Status_Register(); 
    
    if (0xFFU == (status_read_first_time & 0xFFU ) ) 
    {
        result = 1;   
        *out_data = status_read_first_time;  
        goto END_PROCESS;  
    }
    
    if (0xFFU == ( (status_read_first_time >> 8) & 0xFFU ) ) 
    {
         result = 2;   
        *out_data = status_read_first_time;  
        goto END_PROCESS;    
    }
    
    
    if ( (0x19 == ( (status_read_first_time >> 2) & 0x1FU) ) && (0 == (status_read_first_time & BIT14) ) )  
    {
        result = 0;  
        *out_data = status_read_first_time;   
    }
    else
    {
#if 0
       status1 =   status_read_first_time & 0xFFU; 
       status1 = (status1 & (~(0x1FU << 2)) ) | (0x19U << 2);    
       status2 = (status_read_first_time >> 8) & 0xFFU;  
       status2 = status2 & (~BIT6); 
       SPI_Read_Write_Register(status1, status2);   // Lock 4KB, Quad Enable       
#else      
       SPI_Read_Write_Register(0x64, 0x02);   // Lock 4KB, Quad Enable  
#endif 
       
       status_read_second_time = SPI_Read_Status_Register();    
       if ( (0x19 == ( (status_read_second_time >> 2) & 0x1FU) ) && (0 == (status_read_second_time & BIT14) ) )  
       {
          result = 0;    
          *out_data = status_read_second_time;   
       }
       else
       {
          result = 3;    
          *out_data = status_read_second_time;    
       }
    }
    
    END_PROCESS:  
    HAL_NORFLASH_ExitCritical(sr); 
    
    return result;  
}

uint8_t SPI_UNProtect(uint16_t *out_data)  
{
    uint32_t sr; 
    uint16_t status_read1, status_read2;  
    uint8_t status1, status2, result;  
     
    result = 0;
    status_read1 = 0; 
    status_read2 = 0; 
    
    sr = HAL_NORFLASH_EnterCritical(); 
    status_read1 = SPI_Read_Status_Register(); 
    
    status1 =   status_read1 & 0xFFU; 
    status1 = (status1 & (~(0x1FU << 2)) );    
    status2 = (status_read1 >> 8) & 0xFFU;  
    status2 = status2 & (~BIT6); 
       
    SPI_Read_Write_Register(status1, status2);   
       
    status_read2 = SPI_Read_Status_Register();    
    *out_data = status_read2;  
       
    HAL_NORFLASH_ExitCritical(sr); 
    
    return result;  
}






